package com.topisv.tms.rest.qimen.qmservice;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXB;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.qimen.QmResendInfo;
import com.topisv.tms.entity.stock.check.CheckPlan;
import com.topisv.tms.entity.stock.check.CheckPlanItem;
import com.topisv.tms.exception.ErrorCode;
import com.topisv.tms.exception.PaiUException;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.rest.qimen.qmentity.request.stockreport.Item;
import com.topisv.tms.rest.qimen.qmentity.request.stockreport.StockReport;
import com.topisv.tms.rest.qimen.qmentity.response.QMReponse;
import com.topisv.tms.rest.qimen.qmsend.QmRequestSender;
import com.topisv.tms.rest.qimen.request.RequestMethodType;
import com.topisv.tms.rest.qimen.request.RequestParams;
import com.topisv.tms.service.stock.check.CheckPlanItemService;
import com.topisv.tms.service.stock.check.CheckPlanService;
import com.topisv.tms.utils.DateUtils;
import com.topisv.tms.utils.InitProperties;
import com.topisv.tms.utils.rule.TMSTransportRule;

/**
 * 库存盘点通知接口 create by gaohuan 2015-05-09
 * */
@Component
@Transactional(readOnly =  false)
@Lazy(false)
public class StockReportService  extends QmRequestSender<CheckPlan> {
	
	private static final Logger logger = LoggerFactory.getLogger(StockReportService.class);
	@Autowired
	private EdiGoodsSkuDao ediGoodsSkuDao;
	@Autowired
	private CheckPlanService checkPlanService;
	@Autowired
	private CheckPlanItemService checkPlanItemService;
	@Autowired
	private QmResendInfoService qmResendInfoService;
	
	@Transactional(readOnly = false,rollbackFor=Exception.class,propagation=Propagation.REQUIRED)
	public String execute(CheckPlan checkPlanParam,RequestParams sendParams)throws PaiUException{
		//设置不由发送器自动发送
		
		String result = "success";
		
//		CheckPlan checkPlanParam = (CheckPlan)params.get("CheckPlan");
		if(checkPlanParam==null){
			logger.info("checkPlanParam 为空");
			return null;
		}
		try{
			Map<String,EdiGoodsSku> cacheSku = new HashMap<String,EdiGoodsSku>();
			
			CheckPlan checkPlan = checkPlanService.loadById(checkPlanParam.getId());
			
			sendParams.getParams().put("customerId", checkPlan.getCustomerCode());
			
			List<CheckPlanItem> itemList = checkPlanItemService.loadByPlanCode(checkPlan.getPlanCode());
			int pageSize = 5000;
			int index = 0;
			int currentPage = 1;
			int totalPage = (itemList.size()%pageSize)==0?(itemList.size()/pageSize):(itemList.size()/pageSize)+1;
			
			StockReport dp = new StockReport();
			dp.setTotalPage(totalPage+"");
			dp.setCurrentPage((currentPage++)+"");
			dp.setPageSize(pageSize+"");
			dp.setWarehouseCode(checkPlan.getWarehouseCode());
			dp.setCheckOrderId(checkPlan.getPlanCode());
			dp.setOrderType("PD");
			dp.setOwnerCode(checkPlan.getCustomerCode());
			dp.setCheckTime(DateUtils.getCurrentDate("yyyy-MM-dd HH:mm:ss"));
			dp.setOutBizCode(TMSTransportRule.generateByPreFixAndSuffix("QM","SR"));
			dp.setRemark("");
			dp.setItems(new ArrayList<Item>());
			
			for(CheckPlanItem cpItem:itemList) {
				/**
				 * 正品
				 */
				Item itemZP = new Item();
				EdiGoodsSku ediGoodsSkuZP = getEdiGoodsSku(checkPlan.getCustomerCode()	, cpItem.getSku(), cacheSku);
				
				itemZP.setItemCode(ediGoodsSkuZP==null?"":ediGoodsSkuZP.getBar());
				itemZP.setItemId(ediGoodsSkuZP==null?"":ediGoodsSkuZP.getId()+"");
				itemZP.setInventoryType("ZP");
				itemZP.setQuantity((cpItem.getSalesNumFix()==null)?"0":cpItem.getSalesNumFix()+"");
				itemZP.setBatchCode("");
//				itemZP.setProductDate("");
//				itemZP.setExpireDate("");
				itemZP.setProduceCode("");
				itemZP.setSnCode("");
				itemZP.setRemark("");
				
				dp.getItems().add(itemZP);
				
				
				index++;
				String sendUrl = "";
				String sendXml = "";
				
					//满足 limit  发送一次
					if(index==pageSize){
						dp = new StockReport();
						dp.setTotalPage(totalPage+"");
						dp.setCurrentPage((currentPage++)+"");
						dp.setPageSize(pageSize+"");
						dp.setWarehouseCode(checkPlan.getWarehouseCode());
						dp.setCheckOrderId(checkPlan.getPlanCode());
						dp.setOrderType("PD");
						dp.setOwnerCode(checkPlan.getCustomerCode());
						dp.setOutBizCode(TMSTransportRule.generateByPreFixAndSuffix("QM","SR"));
						dp.setRemark("");
						dp.setItems(new ArrayList<Item>());
						
						StringWriter writer = new StringWriter();
						JAXB.marshal(dp,writer);
						
						int reSendCount = 0;
						while(true){
							sendXml = writer.toString();
							sendParams.setRequestXml(sendXml);
							sendUrl = super.getSendUrl(sendParams);
							try{
								logger.info("stock report sendXml:"+sendXml);
								String responseXml = pub2(sendUrl, sendXml);
								logger.info("responseXml:"+responseXml);
								QMReponse qmp = JAXB.unmarshal(new StringReader(responseXml), QMReponse.class);;
								if("success".equals(qmp.getFlag())){
									result = "success";
								}else {
									result = "failure";
								}
								logger.info("盘点通知回传结果  Flag:"+qmp.getFlag()+" Code:"+qmp.getCode()+" Message:"+qmp.getMessage());
								break;
							}catch(Exception e){
								if(reSendCount >= 5){
									result = "failure";
									logger.info("奇门回传结果:"+result);
									QmResendInfo qmResendInfo = new QmResendInfo(sendXml); 
									qmResendInfoService.save(qmResendInfo);
									logger.error("奇门接口调用失败5次 写入重发记录表");
									break;
								}
								reSendCount++;
								logger.info("重试次数"+reSendCount);
								logger.info("", e);
							}
						}
						index=0;
					}else if(itemList.size()==index) {
						/**
						 * 由于ERP只能接收相同SKU一次，因此item只保存一个相同SKU，合并数量
						 */
						List<Item> its = mergeItem(dp.getItems());
						dp.setItems(its);
						//到最后直接发送
						StringWriter writer = new StringWriter();
						JAXB.marshal(dp,writer);
						sendXml = writer.toString();
						sendParams.setRequestXml(sendXml);
						sendUrl = super.getSendUrl(sendParams);
						int reSendCount = 0;
						while(true){
							try{
								logger.info("stock report sendXml:"+sendXml);
								String responseXml = pub2(sendUrl, sendXml);
								logger.info("StockReportService:"+responseXml);
								QMReponse qmp = JAXB.unmarshal(new StringReader(responseXml), QMReponse.class);;
								if("success".equals(qmp.getFlag())){
									result = "success";
								}else {
									result = "failure";
								}
								logger.info("盘点通知回传结果  Flag:"+qmp.getFlag()+" Code:"+qmp.getCode()+" Message:"+qmp.getMessage());
								break;
							}catch(Exception e){
								if(reSendCount >= 5){
									result = "failure";
									logger.info("奇门回传结果:"+result);
									QmResendInfo qmResendInfo = new QmResendInfo(sendXml); 
									qmResendInfoService.save(qmResendInfo);
									logger.error("奇门接口调用失败5次 写入重发记录表");
									break;
								}
								reSendCount++;
								logger.info("重试次数"+reSendCount);
								logger.info("", e);
							}
						}
					}
				
				
				/**
				 * 残次品
				 */
				Item itemCC = new Item();
				EdiGoodsSku ediGoodsSkuCC = getEdiGoodsSku(checkPlan.getCustomerCode()	, cpItem.getSku(), cacheSku);
				if(ediGoodsSkuCC==null){System.out.println(cpItem.getSku());}
				itemCC.setItemCode(ediGoodsSkuCC==null?"":ediGoodsSkuCC.getBar());
				itemCC.setItemId(ediGoodsSkuCC==null?"":ediGoodsSkuCC.getId()+"");
				itemCC.setInventoryType("CC");
				itemCC.setQuantity((cpItem.getUnusedNumFix()==null)?"0":cpItem.getUnusedNumFix()+"");
				itemCC.setBatchCode("");
//				itemCC.setProductDate("");
//				itemCC.setExpireDate("");
				itemCC.setProduceCode("");
				itemCC.setSnCode("");
				itemCC.setRemark("");
				
				dp.getItems().add(itemCC);
			}
			
			
			
		}catch(PaiUException e){
        	throw new PaiUException(ErrorCode.DATA_ERROR);
		}catch(Exception e){e.printStackTrace();
        	throw new PaiUException(ErrorCode.DATA_ERROR);
		}
		return null;
	}
	
	public EdiGoodsSku getEdiGoodsSku(String customerCode,String sku,Map<String,EdiGoodsSku> cacheSku){
		EdiGoodsSku ediGoodsSku = null;
		if(cacheSku.get(customerCode+"_"+sku) != null){
			ediGoodsSku = cacheSku.get(customerCode+"_"+sku);
		}else {
			ediGoodsSku = ediGoodsSkuDao.findByCustomerCodeAndSku(customerCode ,sku);
		}
		return ediGoodsSku;
	}
	
	@Override
	public RequestParams setupParam(RequestParams rp) {
		
		Map<String,String> params = new HashMap<String,String>();
		params.put("method", RequestMethodType.STOCK_REPORT.getType());
		params.put("format", InitProperties.get("qm.format"));
		params.put("app_key", InitProperties.get("regAppKey"));
		params.put("v", InitProperties.get("qm.v"));
		params.put("sign_method", InitProperties.get("qm.sign_method"));
		params.put("customerId", "");//暂未定
		rp.setSecret(InitProperties.get("regAppSecret"));
		rp.setParams(params);
		return rp;
	}
	/**
	 * 合并相同sku的商品变化量,忽略正品和残次品
	 * @autor caomingwu
	 * @time 2016/5/26
	 */
	public List<Item> mergeItem(List<Item> items){
		List<Item> mergeItems = new ArrayList<Item>() ;
		Map map = new HashMap() ; 
		for(Item item:items){
			if(map.containsKey(item.getItemCode())){
				for(Item mergeitem:mergeItems){
					if(mergeitem.getItemCode().equals(item.getItemCode())){
						mergeitem.setQuantity(String.valueOf(Integer.parseInt(mergeitem.getQuantity())+Integer.parseInt(item.getQuantity())));
					}
				}
			}else{
				mergeItems.add(item);
				map.put(item.getItemCode(), item.getItemCode()) ;
			}
		}
		return mergeItems ; 
	}
}
